package org.wesc.boot.service.system.role;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wesc.boot.dao.domain.QueryRequest;
import org.wesc.boot.dao.entity.Role;
import org.wesc.boot.dao.entity.RoleMenu;
import org.wesc.boot.dao.entity.UserRole;
import org.wesc.boot.dao.mapper.RoleMapper;
import org.wesc.boot.dao.mapper.RoleMenuMapper;
import org.wesc.boot.dao.mapper.UserRoleMapper;
import org.wesc.boot.dao.model.RoleQueryModel;
import org.wesc.boot.dao.model.RoleResultModel;
import org.wesc.boot.dao.service.RoleService;
import org.wesc.boot.dao.utils.SortUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 角色服务
 *
 * @author Wesley Cheung
 * @date 2019/7/29 22:14
 */
@Slf4j
@Service
public class RoleAdvanceService {

    private RoleMapper roleMapper;

    private RoleService roleService;

    private UserRoleMapper userRoleMapper;

    private RoleMenuMapper roleMenuMapper;

    @Autowired
    public void setRoleMapper(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    @Autowired
    public void setRoleService(RoleService roleService) {
        this.roleService = roleService;
    }

    @Autowired
    public void setUserRoleMapper(UserRoleMapper userRoleMapper) {
        this.userRoleMapper = userRoleMapper;
    }

    @Autowired
    public void setRoleMenuMapper(RoleMenuMapper roleMenuMapper) {
        this.roleMenuMapper = roleMenuMapper;
    }

    /**
     * 角色查询
     */
    public IPage<Role> findRoles(RoleQueryModel model, QueryRequest request) {
        try {
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();

            if (StringUtils.isNotBlank(model.getRoleName())) {
                queryWrapper.eq(Role::getRoleName, model.getRoleName());
            }
            if (StringUtils.isNotBlank(model.getCreateTimeFrom()) && StringUtils.isNotBlank(model.getCreateTimeTo())) {
                queryWrapper
                        .ge(Role::getCreateTime, model.getCreateTimeFrom())
                        .le(Role::getCreateTime, model.getCreateTimeTo());
            }
            Page<Role> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            return roleService.page(page,queryWrapper);
        } catch (Exception e) {
            log.error("获取角色信息失败", e);
            return null;
        }
    }

    /**
     * 根据角色名称查找角色
     */
    public Role findByName(String roleName) {
        return roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleName, roleName));
    }

    /**
     * 创建角色，并且赋予角色菜单权限
     */
    public void createRole(RoleResultModel model) {
        model.setCreateTime(LocalDateTime.now());
        roleMapper.insert(model);

        String[] menuIds = model.getMenuId().split(StringPool.COMMA);
        saveRoleMenus(model, menuIds);
    }

    /**
     * 批量删除角色
     */
    public void deleteRoles(String[] roleIds) {
        List<Long> list = new ArrayList<>();
        for(String roleId : roleIds) {
            list.add(Long.valueOf(roleId));
        }

        // 删除role-menu
        deleteRoleMenusByRoleId(roleIds);

        // 删除user-role
        deleteUserRolesByRoleId(roleIds);

        // 删除角色
        roleMapper.deleteBatchIds(list);
    }

    /**
     * 修改角色
     */
    public void updateRole(RoleResultModel roleResultModel) {
        // 保存role
        roleResultModel.setModifyTime(LocalDateTime.now());
        roleMapper.updateById(roleResultModel);

        // 保存role-menu: 先删除已有的，再把编辑后的全部加入
        roleMenuMapper.delete(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, roleResultModel.getRoleId()));
        String[] menuIds = roleResultModel.getMenuId().split(StringPool.COMMA);
        saveRoleMenus(roleResultModel, menuIds);
    }

    /**
     * 保存角色菜单对应关系
     */
    private void saveRoleMenus(Role role, String[] menuIds) {
        Arrays.stream(menuIds).forEach(menuId -> {
            RoleMenu rm = new RoleMenu();
            rm.setMenuId(Long.valueOf(menuId));
            rm.setRoleId(role.getRoleId());
            this.roleMenuMapper.insert(rm);
        });
    }

//    /**
//     * 查找这些角色关联了那些用户
//     */
//    public List<String> findUserIdsByRoleId(String[] roleIds) {
//
//        List<UserRole> list = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>().in(UserRole::getRoleId, String.join(",", roleIds)));
//        return list.stream().map(userRole -> String.valueOf(userRole.getUserId())).collect(Collectors.toList());
//    }

    /**
     * 批量删除角色-菜单关联
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteRoleMenusByRoleId(String[] roleIds) {
        List<String> list = Arrays.asList(roleIds);
        roleMenuMapper.delete(new LambdaQueryWrapper<RoleMenu>().in(RoleMenu::getRoleId, list));
    }

    /**
     * 批量删除user-role关联
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserRolesByRoleId(String[] roleIds) {
        List<String> list = Arrays.asList(roleIds);
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().in(UserRole::getRoleId, list));
    }

}
